package com.young.config;

import com.github.benmanes.caffeine.cache.*;
import com.young.entity.User;
import com.young.mapper.UserMapper;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Configuration
public class CaffeineConfig {
    @Bean
    @Qualifier(value = "caffeineCache")
    public Cache caffeineCache(){
        return Caffeine.newBuilder()
                //设置10秒后过期,方便后续观察现象
                .expireAfterWrite(10, TimeUnit.SECONDS)
                //初始容量为100
                .initialCapacity(100)
                //最大容量为200
                .maximumSize(200)
                .build();
    }

    @Bean
    @Qualifier(value = "manualCaffeineCache")
    public Cache manualCaffeineCache(){
        return Caffeine.newBuilder()
                .expireAfterWrite(10,TimeUnit.SECONDS)
                .initialCapacity(50)
                .maximumSize(100)
                .build();
    }


    @Bean
    @Qualifier(value = "loadingCaffeineCache")
    public LoadingCache<String, Object> loadingCaffeineCache(){
        return Caffeine.newBuilder()
                .expireAfterWrite(60, TimeUnit.SECONDS)
                .maximumSize(500)
                .build(new CacheLoader<String, Object>() {
                    //缓存未命中时，使用下面的方法生成value
                    @Override
                    public @Nullable Object load(@NonNull String key) throws Exception {
                        User user=new User();
                        user.setId(-1);
                        user.setUsername(key);
                        user.setPassword(key);
                        return user;
                    }
                    @Override
                    public Map<String,Object>loadAll(Iterable<? extends String>keys){
                        Map<String,Object>map=new HashMap<>();
                        for (String key:keys){
                            User user=new User();
                            user.setId(-1);
                            user.setUsername(key);
                            user.setPassword(key);
                            map.put(key,user);
                        }
                        return map;
                    }
                });
    }

    @Bean
    @Qualifier(value = "listenerCaffeineCache")
    public Cache listenerCaffeineCache(){
        return Caffeine.newBuilder()
                .expireAfterWrite(10,TimeUnit.SECONDS)
                .initialCapacity(100)
                .maximumSize(200)
                .evictionListener(new RemovalListener<String, Object>() {
                    @Override
                    public void onRemoval(@Nullable String key, @Nullable Object value, @NonNull RemovalCause removalCause) {
                        System.out.println("evictionListener:key="+key+",value="+value+",removalCause="+removalCause);
                    }
                }).removalListener((key,value,cause)->{
                    System.out.println("removalListener:key="+key+",value="+value+",cause="+cause);
                })
                .build();
    }
}
